'''
Author: Leo.wang wanglizhigs@163.com
Date: 2025-10-31 22:44:42
LastEditors: Leo.wang wanglizhigs@163.com
LastEditTime: 2025-10-31 22:46:00
FilePath: /medical-companion-server-python/app/common/auth_combined.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from django.conf import settings
import jwt
from rest_framework_simplejwt.authentication import JWTAuthentication
from app.user.models import McUser
from app.manage.models import McManage

class CombinedJWTAuthentication(BaseAuthentication):
    """
    支持两种登录：
    1. 微信小程序用户（自定义 JWT）
    2. 后台管理员（SimpleJWT）
    """
    keyword = 'Bearer'

    def authenticate(self, request):
        auth = request.headers.get('Authorization')
        if not auth:
            return None

        parts = auth.split()
        if len(parts) != 2 or parts[0] != self.keyword:
            raise exceptions.AuthenticationFailed('Invalid Authorization header')
        token = parts[1]

        # ---- 尝试自定义 WeChat token ----
        try:
            payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=['HS256'])
            openid = payload.get('openid')
            if openid:
                user = McUser.objects.filter(open_id=openid).first()
                if user:
                    user.is_authenticated = True
                    user._role_type = 'wechat'  # 自定义标记
                    return (user, payload)
        except Exception:
            pass  # 不打印错误，继续尝试 SimpleJWT

        # ---- 尝试 SimpleJWT（管理员 token）----
        simplejwt_auth = JWTAuthentication()
        try:
            validated = simplejwt_auth.authenticate(request)
            if validated:
                user, token_obj = validated
                user.is_authenticated = True
                user._role_type = 'manage'  # 管理员标记
                return (user, token_obj.payload)
        except Exception:
            raise exceptions.AuthenticationFailed('Invalid token (no valid JWT type found)')

        raise exceptions.AuthenticationFailed('Invalid token')
